﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using YArchitech.Revit;

namespace YJKStairs.CommonUnit
{
	public class BeamGeometryManager
	{
		public BeamGeometryManager(FamilyInstance Beam)
		{
			this.m_Instance = Beam;
			this.m_doc = this.m_Instance.Document;
		}

		private Face GetTopFace()
		{
			Face result = null;
			List<Face> elementAllFace = ElementGeometryManager.GetElementAllFace(this.m_Instance);
			if (0 < elementAllFace.Count)
			{
				foreach (Face face in elementAllFace)
				{
					if (!(null == face) && face.ComputeNormal(UV.Zero).Z > 0.0)
					{
						result = face;
						break;
					}
				}
			}
			return result;
		}

		private Face GetBtmFace()
		{
			Face result = null;
			List<Face> elementAllFace = ElementGeometryManager.GetElementAllFace(this.m_Instance);
			if (0 < elementAllFace.Count)
			{
				foreach (Face face in elementAllFace)
				{
					if (!(null == face) && face.ComputeNormal(UV.Zero).Z < 0.0)
					{
						result = face;
						break;
					}
				}
			}
			return result;
		}

		private double GetYTypeOffset(BeamGeometryPosParamReader.YAlignType yaType)
		{
			double result = 0.0;
			double num = this.GetBeamWidth(this.m_Instance) / 2.0;
			switch (yaType)
			{
			case BeamGeometryPosParamReader.YAlignType.YAT_Left:
				result = -num;
				break;
			case BeamGeometryPosParamReader.YAlignType.YAT_CenterLine:
				result = 0.0;
				break;
			case BeamGeometryPosParamReader.YAlignType.YAT_Origin:
				result = 0.0;
				break;
			case BeamGeometryPosParamReader.YAlignType.YAT_Right:
				result = num;
				break;
			}
			return result;
		}

		private double GetZTypeOffset(BeamGeometryPosParamReader.ZAlignType zaType)
		{
			double result = 0.0;
			double beamHeight = this.GetBeamHeight(this.m_Instance);
			switch (zaType)
			{
			case BeamGeometryPosParamReader.ZAlignType.ZAT_Top:
				result = 0.0;
				break;
			case BeamGeometryPosParamReader.ZAlignType.ZAT_CenterLine:
				result = beamHeight / 2.0;
				break;
			case BeamGeometryPosParamReader.ZAlignType.ZAT_Origin:
				result = beamHeight / 2.0;
				break;
			case BeamGeometryPosParamReader.ZAlignType.ZAT_Bottom:
				result = beamHeight;
				break;
			}
			return result;
		}

		private Curve GetBeamRealLocCurveByType(BeamGeometryPosParamReader.YZAlignType yzType)
		{
			Curve result = null;
			if (yzType != BeamGeometryPosParamReader.YZAlignType.YZAT_Unify)
			{
				if (yzType == BeamGeometryPosParamReader.YZAlignType.YZAT_Independent)
				{
					LocationCurve locationCurve = this.m_Instance.Location as LocationCurve;
					if (locationCurve != null)
					{
						BeamGeometryPosParamReader.YAlignType startYAlignType = BeamGeometryPosParamReader.GetStartYAlignType(this.m_Instance);
						BeamGeometryPosParamReader.ZAlignType startZAlignType = BeamGeometryPosParamReader.GetStartZAlignType(this.m_Instance);
						double startYOffsetParamValue = BeamGeometryPosParamReader.GetStartYOffsetParamValue(this.m_Instance);
						double startZOffsetParamValue = BeamGeometryPosParamReader.GetStartZOffsetParamValue(this.m_Instance);
						double ytypeOffset = this.GetYTypeOffset(startYAlignType);
						double ztypeOffset = this.GetZTypeOffset(startZAlignType);
						double num = startYOffsetParamValue + ytypeOffset;
						double num2 = startZOffsetParamValue + ztypeOffset;
						XYZ xyz = new XYZ(0.0, num, num2);
						BeamGeometryPosParamReader.YAlignType endYAlignType = BeamGeometryPosParamReader.GetEndYAlignType(this.m_Instance);
						BeamGeometryPosParamReader.ZAlignType endZAlignType = BeamGeometryPosParamReader.GetEndZAlignType(this.m_Instance);
						double endZOffsetParamValue = BeamGeometryPosParamReader.GetEndZOffsetParamValue(this.m_Instance);
						double endZOffsetParamValue2 = BeamGeometryPosParamReader.GetEndZOffsetParamValue(this.m_Instance);
						double ytypeOffset2 = this.GetYTypeOffset(endYAlignType);
						double ztypeOffset2 = this.GetZTypeOffset(endZAlignType);
						double num3 = endZOffsetParamValue + ytypeOffset2;
						double num4 = endZOffsetParamValue2 + ztypeOffset2;
						XYZ xyz2 = new XYZ(0.0, num3, num4);
						XYZ endPoint = locationCurve.Curve.GetEndPoint(0);
						XYZ endPoint2 = locationCurve.Curve.GetEndPoint(1);
						XYZ xyz3 = endPoint.Add(xyz);
						XYZ xyz4 = endPoint2.Add(xyz2);
						if (xyz3 != null && xyz4 != null)
						{
							result = Line.CreateBound(xyz3, xyz4);
						}
					}
				}
			}
			else
			{
				LocationCurve locationCurve2 = this.m_Instance.Location as LocationCurve;
				if (locationCurve2 != null)
				{
					BeamGeometryPosParamReader.YAlignType yalignType = BeamGeometryPosParamReader.GetYAlignType(this.m_Instance);
					BeamGeometryPosParamReader.ZAlignType zalignType = BeamGeometryPosParamReader.GetZAlignType(this.m_Instance);
					double yoffsetParamValue = BeamGeometryPosParamReader.GetYOffsetParamValue(this.m_Instance);
					double zoffsetParamValue = BeamGeometryPosParamReader.GetZOffsetParamValue(this.m_Instance);
					double ytypeOffset3 = this.GetYTypeOffset(yalignType);
					double ztypeOffset3 = this.GetZTypeOffset(zalignType);
					double num5 = yoffsetParamValue + ytypeOffset3;
					double num6 = zoffsetParamValue + ztypeOffset3;
					Transform transform = Transform.CreateTranslation(new XYZ(0.0, num5, num6));
					result = locationCurve2.Curve.CreateTransformed(transform);
				}
			}
			return result;
		}

		private double GetBeamHeight(FamilyInstance famBeam)
		{
			double result = 0.0;
			if (famBeam != null)
			{
				Parameter parameter = famBeam.Symbol.GetParameter("h");
				if (parameter != null)
				{
					result = parameter.AsDouble();
				}
			}
			return result;
		}

		private double GetBeamWidth(FamilyInstance famBeam)
		{
			double result = 0.0;
			if (famBeam != null)
			{
				Parameter parameter = famBeam.Symbol.GetParameter("b");
				if (parameter != null)
				{
					result = parameter.AsDouble();
				}
			}
			return result;
		}

		public Curve GetBeamRealLocationCurve()
		{
			Curve result = null;
			if (!(this.m_Instance.Location is LocationCurve))
			{
				return result;
			}
			BeamGeometryPosParamReader.YZAlignType yzalignType = BeamGeometryPosParamReader.GetYZAlignType(this.m_Instance);
			return this.GetBeamRealLocCurveByType(yzalignType);
		}

		private FamilyInstance m_Instance;

		private Document m_doc;
	}
}
